package com.hh.base.log;

import android.content.pm.ApplicationInfo;
import android.util.Log;


import com.hh.base.MyUtils;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.UnknownHostException;

/**
 * Created by Haibiao.Li on 2017/4/20 0020
 * <br>Email:lihaibiaowork@gmail.com</br>
 * <p><b>注释：</b></p>
 */

public class SLog{
    public static final int MARK_DEBUG = 1 << 0;
    public static long flag = 0;

    private SLog() {
    }

    private static ILog sLog;

    public static void init(ILog log) {
        sLog = log;
    }

    public static boolean debug() {
        return ((SLog.flag & SLog.MARK_DEBUG) != 0);
    }
    public static boolean debugApp(){
        ApplicationInfo info = MyUtils.mContext.getApplicationInfo();
        return (info != null && ((info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0));
    }

    public static void v(String tag, String format, Object... args) {
        v(tag, String.format(format, args));
    }
    public static void v(String tag, String msg) {
        o(ILog.LEVEL_V, tag, msg);
    }
    public static void v(String tag, Throwable e) {
        v(tag,null,e);
    }
    public static void v(String tag, String msg,Throwable e) {
        o(ILog.LEVEL_V, tag, msg + "\n" + getThrowableMsg(e));
    }


    public static void d(String tag, String format, Object... args) {
        d(tag, String.format(format, args));
    }
    public static void d(String tag, String msg) {
        o(ILog.LEVEL_D, tag, msg);
    }
    public static void d(String tag, Throwable e) {
        d(tag,null,e);
    }
    public static void d(String tag, String msg,Throwable e) {
        o(ILog.LEVEL_D, tag, msg + "\n" + getThrowableMsg(e));
    }


    public static void i(String tag, String format, Object... args) {
        i(tag, String.format(format, args));
    }
    public static void i(String tag, String msg) {
        o(ILog.LEVEL_I, tag, msg);
    }
    public static void i(String tag, Throwable e) {
        i(tag,null,e);
    }
    public static void i(String tag, String msg,Throwable e) {
        o(ILog.LEVEL_I, tag, msg + "\n" + getThrowableMsg(e));
    }

    public static void w(String tag, String format, Object... args) {
        w(tag, String.format(format, args));
    }
    public static void w(String tag, String msg) {
        o(ILog.LEVEL_W, tag, msg);
    }
    public static void w(String tag, Throwable e) {
        w(tag, null, e);
    }
    public static void w(String tag, String msg, Throwable e) {
        o(ILog.LEVEL_W, tag, msg + "\n" + getThrowableMsg(e));
    }

    public static void e(String tag, String format, Object... args) {
        e(tag, String.format(format, args));
    }
    public static void e(String tag, String msg) {
        o(ILog.LEVEL_E, tag, msg);
    }
    public static void e(String tag, Throwable e) {
        e(tag, null, e);
    }
    public static void e(String tag, String msg, Throwable e) {
        o(ILog.LEVEL_E, tag, msg + "\n" + getThrowableMsg(e));
    }

    private static String getThrowableMsg(Throwable e) {
        return String.format("%s:%s\n%s", e.getClass().getSimpleName(), e.getMessage(), getStackTraceString(e));
    }

    public static void o(int level, String tag, String msg) {
        if (sLog == null) {
            switch (level) {
                case ILog.LEVEL_V:
                    Log.v(tag, msg);
                    break;
                case ILog.LEVEL_D:
                    Log.d(tag, msg);
                    break;
                case ILog.LEVEL_I:
                    Log.i(tag, msg);
                    break;
                case ILog.LEVEL_W:
                    Log.w(tag, msg);
                    break;
                case ILog.LEVEL_E:
                    Log.e(tag, msg);
                    break;
                default:
                    Log.v(tag, msg);
                    break;
            }
        } else {
            sLog.print(level, tag, msg);
        }
    }

    /**
     * Handy function to get a loggable stack trace from a Throwable
     *
     * @param tr An exception to log
     */
    public static String getStackTraceString(Throwable tr) {
        if (tr == null) {
            return "";
        }

        // This is to reduce the amount of log spew that apps do in the non-error
        // condition of the network being unavailable.
        Throwable t = tr;
        while (t != null) {
            if (t instanceof UnknownHostException) {
                return "";
            }
            t = t.getCause();
        }

        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        tr.printStackTrace(pw);
        pw.flush();
        return sw.toString();
    }

    public static void flush() {
        if(sLog != null){
            sLog.flush();
        }
    }
}
